package com.nstskj.study.netty.tcp.netty.protocol.message.in.msg;

import cn.hutool.core.util.ArrayUtil;
import com.nstskj.study.netty.tcp.netty.protocol.annotation.MessageCommandAnnotation;
import com.nstskj.study.netty.tcp.netty.protocol.definition.annotation.MessageField;
import com.nstskj.study.netty.tcp.netty.protocol.definition.enums.MsgFieldTypeEnums;
import com.nstskj.study.netty.tcp.netty.protocol.endpoint.DeviceEndpoint;
import com.nstskj.study.netty.tcp.netty.protocol.enums.IotDeviceProtocolCmdEnum;
import com.nstskj.study.netty.tcp.netty.protocol.message.in.msg.base.AbstractInputNetTcpMessage;
import lombok.Data;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ZhouChuGang
 * @version 1.0
 * @project nstskj-study-netty-tcp-spring
 * @date 2021/4/20 20:58
 * @Description 设备注册消息
 */
@Data
@MessageCommandAnnotation(value = IotDeviceProtocolCmdEnum.DEVICE_REGISTER)
public class DeviceRegisterCmdMsg extends AbstractInputNetTcpMessage {

    //  序号	域	索引	长度（字节）	说明
    //1	厂家id	0	16	用于表示厂家唯一号
    //2	用户id	16	16	用于表示此设备的用户
    //3	设备id	32	32	设备唯一号
    //4	设备版本号	64	2	设备版本
    //5	端点1地址	66	2	端点1的地址
    //6	端点1类型	68	2	其中bit7表示方向，1表示设备上送，0表示设备接收，其它位保留
    //7	端点2地址	70	2	端点2的地址
    //8	端点2类型	72	2	其中bit7表示方向，1表示服务端下发，0表示设备上送，其它位保留

    /**
     * 端点数据长度
     */
    private static final int DEVICE_ENDPOINT_LENGTH = 4;

    /**
     * 厂家id  16字节
     */
    @MessageField(fieldType = MsgFieldTypeEnums.STRING_TYPE, startIndex = 0, length = 16)
    private String factoryId;

    /**
     * 用户id  16字节
     */
    @MessageField(fieldType = MsgFieldTypeEnums.STRING_TYPE, startIndex = 16, length = 16)
    private String userId;

    /**
     * 设备id  32字节
     */
    @MessageField(fieldType = MsgFieldTypeEnums.STRING_TYPE, startIndex = 32, length = 32)
    private String deviceId;

    /**
     * 设备版本
     */
    @MessageField(fieldType = MsgFieldTypeEnums.STRING_TYPE, startIndex = 64, length = 2)
    private String deviceVersion;

    /**
     * 端点集合
     */
    private Map<Short, DeviceEndpoint> endpointMap = new ConcurrentHashMap<>();

    /**
     * 命令数据自定义处理
     */
    @Override
    public void decoderCmdData() {
        byte[] cmdData = this.getCmdData();
        int endIndex = IotDeviceProtocolCmdEnum.DEVICE_REGISTER.getCmdDataMinLen();
        int endLen = cmdData.length - endIndex;
        int endDataLen = DEVICE_ENDPOINT_LENGTH;
        if (endLen > endDataLen) {
            //存在端点信息 ,得到端点数量
            int i = endLen / endDataLen;
            //拷贝端点信息
            byte[] bytes = new byte[i * endDataLen];
            ArrayUtil.copy(cmdData, endIndex, bytes, 0, bytes.length);
            //开始解析一个个端点
            for (int j = 0; j < i; j++) {
                //5	端点1地址	        66	2	端点1的地址
                //6	端点1类型及缓存长度	68	2	其中bit15表示方向，1表示设备上送，0表示设备接收，bit0~bit15表示缓存长度
                short address = (short) ((short) bytes[j * endDataLen] * 256 + (short) bytes[j * endDataLen + 1]);
                short typeLen = (short) ((short) bytes[j * endDataLen + 2] * 256 + (short) bytes[j * endDataLen + 3]);
                DeviceEndpoint deviceEndpoint = new DeviceEndpoint(address, (typeLen & 0X8000) > 0, typeLen & 0X7FFF);
                //放入端点集合
                endpointMap.put(address, deviceEndpoint);
            }
        }
    }
}
